<?php
/*************************************************************************

$Id: osc22ms1.php 543 2010-07-15 12:47:10Z dis $

iclear payment system - because secure is simply secure
http://www.iclear.de

Copyright (c) 2001 - 2009 iclear

Released under the GNU General Public License

************************************************************************

All rights reserved.

This program is free software licensed under the GNU General Public License (GPL).

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA

*************************************************************************/

define('IC_WRAPPER_ID', 'osc22ms1');

class IclearWrapper extends IclearWrapperBase {
	var $id;
	 
	var $lang;
	// iclear DMI -> added global order var
	var $code;

	var $title;

	var $description;

	var $enabled;

	var $order;

	var $orderStatusID;

	var $specialItemID = 0;

	var $addressKeysMask = array(
      'name' => '',
      'company' => '',
      'street_address' => 'info',
      'suburb' => '',
      'city' => '',
      'postcode' => '',
      'state' => '',
	);

	var $addressKeysUnmask = array(
      'company',
      'street_address',
      'suburb',
      'city',
      'postcode',
      'state',
	);

	/**
	 * iclear executed in an iframe
	 * @var boolean
	 */
	var $bIframe;

	// class constructor
	function IclearWrapper(&$icCore) {
		$this->icVersion = '$Id: osc22ms1.php 543 2010-07-15 12:47:10Z dis $';

		global $order;
		parent::IclearWrapperBase($icCore);
		 
		$this->id = IC_WRAPPER_ID;
		 
		 
		$this->code = 'iclear';
		$lang =& $icCore->getLanguage();
		$this->title = preg_match('/modules\.php|orders\.php/', $_SERVER['SCRIPT_FILENAME']) ? $lang->getParam('MODULE_TITLE_ADMIN') :
		$lang->getParam('MODULE_TITLE');

		$this->description =  $lang->getParam('DESCRIPTION');
		$this->sort_order =  $lang->getParam('SORT_ORDER');

		$this->lang =& $lang;

		$this->enabled = $this->enabled();
		if (isset($order) && is_object($order)) $this->update_status();
		 
		$this->bIframe = $this->iframe();
	}

	function dbQuery($sql) {
		return tep_db_query($sql);
	}

	function dbFetchRecord($sql) {
		$rec = false;
		if($qry = $this->dbQuery($sql)) {
			$rec = tep_db_fetch_array($qry);
		}
		return $rec;
	}

	function dbLastInsertID() {
		return tep_db_insert_id();
	}

	function title() {
		return preg_match('/modules\.php|orders\.php/', $_SERVER['SCRIPT_FILENAME']) ? $this->lang->getParam('MODULE_TITLE_ADMIN')
		: $this->lang->getParam('MODULE_TITLE');
	}

	function enabled() {
		return (defined('MODULE_PAYMENT_ICLEAR_STATUS') && MODULE_PAYMENT_ICLEAR_STATUS == 'True') ? true : false;
	}

	function sortOrder() {
		return (defined('MODULE_PAYMENT_ICLEAR_SORT_ORDER')) ? MODULE_PAYMENT_ICLEAR_SORT_ORDER : 0;
	}

	function iframe() {
		return (defined('MODULE_PAYMENT_ICLEAR_IFRAME') && MODULE_PAYMENT_ICLEAR_IFRAME == 'True') ? true : false;
	}

	function getOrder() {
		global $order;
		return $order;
	}

	function currency() {
		$rv = '';
		if($order =& $this->getOrder()) {
			$rv = $order->info['currency'];
		}
		return $rv;
	}

	function orderItemCount() {
		$rv = 0;
		 
		if($order =& $this->getOrder()) {
			$rv = sizeof($order->products);
		}
		return $rv;
	}

	function itemPrice($priceNet = 0, $quantitiy = 0, $tax = 0) {
		$currencies = $GLOBALS['currencies'];
		$rv = 0;
		if($currencies && $priceNet && $quantitiy) {
			if($tax && DISPLAY_PRICE_WITH_TAX != 'true') {
				$priceNet = tep_round($priceNet, $currencies->currencies[DEFAULT_CURRENCY]['decimal_places'])
				+ tep_calculate_tax($priceNet, $tax);
			}
			$rv = $currencies->display_price($priceNet, $tax, $quantitiy);
			// extract price
			preg_match('/([0-9.,]+)/', $rv, $match);
			// get number and decimals (remove thousand sep chars)
			preg_match('/(.*)[,.](\d{2})$/', $match[1], $match);
			$rv = round(preg_replace('/[^0-9]/', '', $match[1]) . '.' . $match[2], 4);
		}
		return $rv;
	}

	function nextOrderItem() {
		$item = false;
		if(version_compare(PHP_VERSION, '5.0.0', '<')) {
			static $id;
			if(!isset($id)) {
				$id = 0;
			}
			$this->currentProductID = $id;
		} else {
			$id =& $this->currentProductID;
		}

		if($order =& $this->getOrder()) {
			if($id < sizeof($order->products)) {
				$rec = $order->products[$id];
				$item[IC_SOAP_ITEM_NO] = $rec['id'];
				// removing OSC attribute encoding from productID
				$item[IC_SOAP_ITEM_NO] = preg_replace('/\{.*/', '', $item[IC_SOAP_ITEM_NO]);
				$item[IC_SOAP_ITEM_TITLE] = $this->encodeUTF8($rec['qty'] . ' x ' . $rec['name']);
				// adding the attributes to the title
				if(isset($rec['attributes']) && is_array($rec['attributes'])) {
					foreach($rec['attributes'] AS $att) {
						$item[IC_SOAP_ITEM_TITLE] .= $this->encodeUTF8(' | ' . $att['option'] . ': ' . $att['value']);
					}
				}
				$item[IC_SOAP_ITEM_QTY] = 1;
				$item[IC_SOAP_ITEM_PRICE_NET] = $this->itemPrice($rec['final_price'], $rec['qty'], 0);
				$item[IC_SOAP_ITEM_PRICE_GROS] = $this->itemPrice($rec['final_price'], $rec['qty'], $rec['tax']);
				$item[IC_SOAP_ITEM_VAT_RATE] = tep_round($rec['tax'], 2);
			}
			$id++;
		}
		return $item;
	}

	function specialItems() {
		$items = false;
		 
		// add shipping
		$order = $this->getOrder();
		if($order && isset($_SESSION['shipping']['title'])) {
			$item[IC_SOAP_ITEM_NO] = $this->specialItemID; // in osc exists no zero itemID
			$item[IC_SOAP_ITEM_TITLE] = $this->encodeUTF8($_SESSION['shipping']['title']);
			 
			list($classID,) = explode('_', $_SESSION['shipping']['id']);
			if(isset($GLOBALS[$classID]) && is_object($GLOBALS[$classID])) {
				$tax = tep_get_tax_rate($GLOBALS[$classID]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']);
				$item[IC_SOAP_ITEM_PRICE_NET] = $this->itemPrice($_SESSION['shipping']['cost'], 1);
				$item[IC_SOAP_ITEM_PRICE_GROS] =  $item[IC_SOAP_ITEM_PRICE_NET] + $this->itemPrice(tep_calculate_tax($_SESSION['shipping']['cost'], $tax), 1);
			} else {
				$item[IC_SOAP_ITEM_PRICE_GROS] = $item[IC_SOAP_ITEM_PRICE_NET] = $this->itemPrice($_SESSION['shipping']['cost'], 1);
				$tax = 0;
			}
			$item[IC_SOAP_ITEM_QTY] = 1;
			$item[IC_SOAP_ITEM_VAT_RATE] = $tax;
			$items[] = $item;
		}
		 
		// check if low orderfee is given
		if( isset($GLOBALS['ot_loworderfee']) && sizeof($GLOBALS['ot_loworderfee']->output) ) {
			$sql = 'SELECT tax_rate FROM ' . TABLE_TAX_RATES . ' tax, ' . TABLE_CONFIGURATION . ' config WHERE config.configuration_key="MODULE_ORDER_TOTAL_LOWORDERFEE_TAX_CLASS" AND tax.tax_class_id = config.configuration_value';

			if($taxRes = $this->dbFetchRecord($sql)) {
				$taxRate = tep_round($taxRes['tax_rate'], 1);
			} else {
				$taxRate = '0.0';
			}
			$item[IC_SOAP_ITEM_NO] = --$this->specialItemID;
			$item[IC_SOAP_ITEM_TITLE] = $this->encodeUTF8($GLOBALS['ot_loworderfee']->title);
			$item[IC_SOAP_ITEM_QTY] = 1;
			$sql = 'SELECT configuration_value AS loworderfee FROM ' . TABLE_CONFIGURATION . ' WHERE configuration_key="MODULE_ORDER_TOTAL_LOWORDERFEE_FEE"';
			if($feeRes = $this->dbFetchRecord($sql)) {
				$item[IC_SOAP_ITEM_PRICE_NET] = $this->itemPrice($feeRes['loworderfee'], 1);
				$item[IC_SOAP_ITEM_PRICE_GROS] = $this->itemPrice($feeRes['loworderfee'], 1, $taxRate);
			} else {
				$item[IC_SOAP_ITEM_PRICE_NET] = $item[IC_SOAP_ITEM_PRICE_GROS] = 0;
			}
			$item[IC_SOAP_ITEM_VAT_RATE] = $taxRate;

			$items[] = $item;
		}
		return $items;
	}

	function &deliveryAddress() {
		$rv = false;
		if($order =& $this->getOrder()) {
			$rec = $order->delivery;
			$params = array(
			IC_SOAP_ADDRESS_SALUTATION => '', // not presented in shopsystem
			IC_SOAP_ADDRESS_FIRSTNAME => $rec['firstname'],
			IC_SOAP_ADDRESS_LASTNAME => $rec['lastname'],
			IC_SOAP_ADDRESS_COMPANY => $rec['company'],
			IC_SOAP_ADDRESS_STREET => $this->parseStreet($rec['street_address']),
			IC_SOAP_ADDRESS_STREET_NO => $this->parseStreetNo($rec['street_address']),
			IC_SOAP_ADDRESS_ZIPCODE => $rec['postcode'],
			IC_SOAP_ADDRESS_CITY => $rec['city'],
			IC_SOAP_ADDRESS_COUNTRY => $rec['country']['iso_code_2'],
			);
			$address =& $this->icCore->getObject('IclearAddress', $instance = true);
			if($address->address($params)) {
				$rv =& $address;
			}

		}
		return $rv;
	}

	function customerInfo() {
		if(!$this->customerInfo) {
			$sql = 'SELECT ' .
                 '* ' .
               'FROM ' . 
			TABLE_CUSTOMERS . ' c ' .
               'LEFT JOIN ' . TABLE_ADDRESS_BOOK . ' ab ON (c.customers_default_address_id = ab.address_book_id) ' .
               'LEFT JOIN ' . TABLE_COUNTRIES . ' co ON (ab.entry_country_id = co.countries_id) ' .
               'WHERE ' .
                 'c.customers_id = "' . tep_db_prepare_input($_SESSION['customer_id']) . '"';
			if($rec = $this->dbFetchRecord($sql)) {
				$info = array(
				IC_SOAP_REG_CUSTOMER_ACQUISE_ID => defined('MODULE_PAYMENT_ICLEAR_ACQUISE_ID') ? MODULE_PAYMENT_ICLEAR_ACQUISE_ID : 0,
				IC_SOAP_REG_CUSTOMER_BANK_ACCOUNT_ID => '',
				IC_SOAP_REG_CUSTOMER_BANK_BIC => '',
				IC_SOAP_REG_CUSTOMER_BANK_BLZ => '',
				IC_SOAP_REG_CUSTOMER_BANK_CUSTOMER => '',
				IC_SOAP_REG_CUSTOMER_BANK_IBAN => '',
				IC_SOAP_REG_CUSTOMER_BANK_NAME => '',
				IC_SOAP_REG_CUSTOMER_COMPANYNAME => $rec['entry_company'],
				IC_SOAP_REG_CUSTOMER_EMAIL => $rec['customers_email_address'],
				IC_SOAP_REG_CUSTOMER_FAX => $rec['customers_fax'],
				IC_SOAP_REG_CUSTOMER_FIRSTNAME => $rec['entry_firstname'],
				IC_SOAP_REG_CUSTOMER_DOB => $rec['customers_dob'],
				IC_SOAP_REG_CUSTOMER_INVOICE_CITY => $rec['entry_city'],
				IC_SOAP_REG_CUSTOMER_INVOICE_COUNTRY => $rec['countries_iso_code_2'],
				IC_SOAP_REG_CUSTOMER_INVOICE_RECEIVER => $rec['entry_firstname'] . ' ' . $rec['entry_lastname'],
				IC_SOAP_REG_CUSTOMER_INVOICE_STREET => $this->parseStreet($rec['entry_street_address']),
				IC_SOAP_REG_CUSTOMER_INVOICE_STREETNO => $this->parseStreetNo($rec['entry_street_address']),
				IC_SOAP_REG_CUSTOMER_INVOICE_ZIPCODE => $rec['entry_postcode'],
				IC_SOAP_REG_CUSTOMER_LASTNAME => $rec['entry_lastname'],
				IC_SOAP_REG_CUSTOMER_PHONE => $rec['customers_telephone'],
				IC_SOAP_REG_CUSTOMER_SALUTATION_ID => $rec['entry_gender'] == 'm' ? 1 : 0, //20110202 CA - fixed salutaion
				IC_SOAP_REG_CUSTOMER_EXT_CUSTOMER_ID => $rec['customers_id'],
				IC_SOAP_REG_CUSTOMER_NEWSLETTER_FLAG => '',
				);

				//20110202 CA - fixed DOB
				$info[IC_SOAP_REG_CUSTOMER_DOB] = str_ireplace(' ', 'T', $rec['customers_dob']);

				$this->customerInfo = $info;
			}

		}
		return $this->customerInfo;
	}


	function sessionID($sessionID = '') {
		return $sessionID ? tep_session_id($sessionID) : tep_session_id();
	}

	function customerID() {
		return isset($GLOBALS['customer_id']) ? $GLOBALS['customer_id'] : 0 ;
	}

	function shopID() {
		return defined('MODULE_PAYMENT_ICLEAR_ID') ? MODULE_PAYMENT_ICLEAR_ID : 0;
	}

	function languageISO() {
		global $language;
		$rv = '';
		if($language) {
			switch($language) {
				case 'english':
					$rv = 'EN';
					break;
					 
				case 'espanol':
					$rv = 'ES';
					break;
					 
				case 'german':
				default:
					$rv = 'DE';
			}
		}
		return $rv;
	}

	function httpHost($https = false) {
		$rv = '';
		if($https && ENABLE_SSL) {
			$rv = HTTPS_SERVER;
		} else {
			$rv = HTTP_SERVER;
		}
		return $rv;
	}

	function redirect($url = '') {
		if($url) {
			tep_redirect($url);
			exit;
		}
	}

	// compatibility with xonic-1.5
	function sessionSavePath() {
		if($this->icCore->cloneID == 'xonic15') {
			$rv = DIR_FS_CATALOG . '' . SESSION_WRITE_DIRECTORY . '/';
		} else {
			$rv = parent::sessionSavePath();
		}
		return $rv;
	}


	function storeOrder() {
		global $cart, $currencies, $customer_id, $language, $languages_id, $order;
		$rc = false;
		 
		if($basket =& $this->icCore->getBasket()) {
			global $SESS_LIFE;

			// $SESS_LIFE used in session modules / functions 2 determine session lifetime (time() + $SESS_LIFE)
			$SESS_LIFE = 1440;
			$icLang = $this->icCore->getLanguage();

			tep_session_name(IC_SESSION_NAME);
			tep_session_id($basket->sessionID());
			tep_session_save_path($this->sessionSavePath());
			tep_session_start();

			// recreate session data from basket 2 prevent logout after redirect iclear -> shopURL!
			$_SESSION = $basket->session();
				
			// set globals - needed 4 OSC mods
			$customer_id = $basket->customerID();
			$order = $basket->getOrder();

			switch($basket->language()) {
				case 'EN':
					$language = 'english';
					break;

				case 'ES':
					$language = 'espanol';
					break;

				case 'DE':
				default:
					$language = 'german';
					break;
			}

			// load needed consts 4 email
			require_once $this->icCore->getPath() . 'includes/languages/' . $language . '/checkout_process.php';
			require_once $this->icCore->getPath() . 'includes/languages/' . $language . '.php';

			// adaption - brandtd: prepare environment 4 basket / session deletion
			$cart =& $_SESSION['cart'];

			// OSC checkout_process.php START
			$order_total_modules = new order_total;
			$order_totals = $order_total_modules->process();
				
			$sql_data_array = array('customers_id' => $customer_id,
			                          'customers_name' => $order->customer['firstname'] . ' ' . $order->customer['lastname'],
			                          'customers_company' => $order->customer['company'],
			                          'customers_street_address' => $order->customer['street_address'],
			                          'customers_suburb' => $order->customer['suburb'],
			                          'customers_city' => $order->customer['city'],
			                          'customers_postcode' => $order->customer['postcode'], 
			                          'customers_state' => $order->customer['state'], 
			                          'customers_country' => $order->customer['country']['title'], 
			                          'customers_telephone' => $order->customer['telephone'], 
			                          'customers_email_address' => $order->customer['email_address'],
			                          'customers_address_format_id' => $order->customer['format_id'], 
			                          'delivery_name' => $order->delivery['firstname'] . ' ' . $order->delivery['lastname'], 
			                          'delivery_company' => $order->delivery['company'],
			                          'delivery_street_address' => $order->delivery['street_address'], 
			                          'delivery_suburb' => $order->delivery['suburb'], 
			                          'delivery_city' => $order->delivery['city'], 
			                          'delivery_postcode' => $order->delivery['postcode'], 
			                          'delivery_state' => $order->delivery['state'], 
			                          'delivery_country' => $order->delivery['country']['title'], 
			                          'delivery_address_format_id' => $order->delivery['format_id'], 
			                          'billing_name' => $order->billing['firstname'] . ' ' . $order->billing['lastname'], 
			                          'billing_company' => $order->billing['company'],
			                          'billing_street_address' => $order->billing['street_address'], 
			                          'billing_suburb' => $order->billing['suburb'], 
			                          'billing_city' => $order->billing['city'], 
			                          'billing_postcode' => $order->billing['postcode'], 
			                          'billing_state' => $order->billing['state'], 
			                          'billing_country' => $order->billing['country']['title'], 
			                          'billing_address_format_id' => $order->billing['format_id'], 
			                          'payment_method' => $order->info['payment_method'], 
			                          'cc_type' => $order->info['cc_type'], 
			                          'cc_owner' => $order->info['cc_owner'], 
			                          'cc_number' => $order->info['cc_number'], 
			                          'cc_expires' => $order->info['cc_expires'], 
			                          'date_purchased' => 'now()', 
			                          'orders_status' => ($basket->status == IC_ORDER_WAIT ? MODULE_PAYMENT_ICLEAR_STATUS_WAIT_ID
			: $order->info['order_status']),
			                          'currency' => $order->info['currency'], 
			                          'currency_value' => $order->info['currency_value']);

			tep_db_perform(TABLE_ORDERS, $sql_data_array);
			$icOrderID = $insert_id = tep_db_insert_id();
			for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
				$sql_data_array = array('orders_id' => $insert_id,
			                            'title' => $order_totals[$i]['title'],
			                            'text' => $order_totals[$i]['text'],
			                            'value' => $order_totals[$i]['value'], 
			                            'class' => $order_totals[$i]['code'], 
			                            'sort_order' => $order_totals[$i]['sort_order']);
				tep_db_perform(TABLE_ORDERS_TOTAL, $sql_data_array);
			}
				
			$customer_notification = (SEND_EMAILS == 'true') ? '1' : '0';
			$sql_data_array = array('orders_id' => $insert_id,
			                          'orders_status_id' => ($basket->status == IC_ORDER_WAIT ? MODULE_PAYMENT_ICLEAR_STATUS_WAIT_ID
			: $order->info['order_status']),
			                          'date_added' => 'now()', 
			                          'customer_notified' => $customer_notification,
			                          'comments' => $order->info['comments']);
			tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
				
			// initialized for the email confirmation
			$products_ordered = '';
			$subtotal = 0;
			$total_tax = 0;
				
			for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
				// Stock Update - Joao Correia
				if (STOCK_LIMITED == 'true') {
					if (DOWNLOAD_ENABLED == 'true') {
						$stock_query_raw = "SELECT products_quantity, pad.products_attributes_filename
			                            FROM " . TABLE_PRODUCTS . " p
			                            LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES . " pa
			                             ON p.products_id=pa.products_id
			                            LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
			                             ON pa.products_attributes_id=pad.products_attributes_id
			                            WHERE p.products_id = '" . tep_get_prid($order->products[$i]['id']) . "'";
						// Will work with only one option for downloadable products
						// otherwise, we have to build the query dynamically with a loop
						$products_attributes = $order->products[$i]['attributes'];
						if (is_array($products_attributes)) {
							$stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
						}
						$stock_query = tep_db_query($stock_query_raw);
					} else {
						$stock_query = tep_db_query("select products_quantity from " . TABLE_PRODUCTS . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
					}
					if (tep_db_num_rows($stock_query) > 0) {
						$stock_values = tep_db_fetch_array($stock_query);
						// do not decrement quantities if products_attributes_filename exists
						if ((DOWNLOAD_ENABLED != 'true') || (!$stock_values['products_attributes_filename'])) {
							$stock_left = $stock_values['products_quantity'] - $order->products[$i]['qty'];
						} else {
							$stock_left = $stock_values['products_quantity'];
						}
						tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
						if ($stock_left < 1) {
							tep_db_query("update " . TABLE_PRODUCTS . " set products_status = '0' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
						}
					}
				}
					
				// Update products_ordered (for bestsellers list)
				tep_db_query("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
					
				$sql_data_array = array('orders_id' => $insert_id,
			                            'products_id' => tep_get_prid($order->products[$i]['id']), 
			                            'products_model' => $order->products[$i]['model'], 
			                            'products_name' => $order->products[$i]['name'], 
			                            'products_price' => $order->products[$i]['price'], 
			                            'final_price' => $order->products[$i]['final_price'], 
			                            'products_tax' => $order->products[$i]['tax'], 
			                            'products_quantity' => $order->products[$i]['qty']);
				tep_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array);
				$order_products_id = tep_db_insert_id();
					
				//------insert customer choosen option to order--------
				$attributes_exist = '0';
				$products_ordered_attributes = '';
				if (isset($order->products[$i]['attributes'])) {
					$attributes_exist = '1';
					for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
						if (DOWNLOAD_ENABLED == 'true') {
							$attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename
			                               from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa 
			                               left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
			                                on pa.products_attributes_id=pad.products_attributes_id
			                               where pa.products_id = '" . $order->products[$i]['id'] . "' 
			                                and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' 
			                                and pa.options_id = popt.products_options_id 
			                                and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' 
			                                and pa.options_values_id = poval.products_options_values_id 
			                                and popt.language_id = '" . $languages_id . "' 
			                                and poval.language_id = '" . $languages_id . "'";
							$attributes = tep_db_query($attributes_query);
						} else {
							$attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
						}
						$attributes_values = tep_db_fetch_array($attributes);
							
						$sql_data_array = array('orders_id' => $insert_id,
			                                'orders_products_id' => $order_products_id, 
			                                'products_options' => $attributes_values['products_options_name'],
			                                'products_options_values' => $attributes_values['products_options_values_name'], 
			                                'options_values_price' => $attributes_values['options_values_price'], 
			                                'price_prefix' => $attributes_values['price_prefix']);
						tep_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array);
							
						if ((DOWNLOAD_ENABLED == 'true') && isset($attributes_values['products_attributes_filename']) && tep_not_null($attributes_values['products_attributes_filename'])) {
							$sql_data_array = array('orders_id' => $insert_id,
			                                  'orders_products_id' => $order_products_id, 
			                                  'orders_products_filename' => $attributes_values['products_attributes_filename'], 
			                                  'download_maxdays' => $attributes_values['products_attributes_maxdays'], 
			                                  'download_count' => $attributes_values['products_attributes_maxcount']);
							tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
						}
						$products_ordered_attributes .= "\n\t" . $attributes_values['products_options_name'] . ' ' . $attributes_values['products_options_values_name'];
					}
				}
				//------insert customer choosen option eof ----
				$total_weight += ($order->products[$i]['qty'] * $order->products[$i]['weight']);
				$total_tax += tep_calculate_tax($total_products_price, $products_tax) * $order->products[$i]['qty'];
				$total_cost += $total_products_price;
					
				$products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] .' (' . $order->products[$i]['model'] . ') = ' .
				$currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n";
			}
				
			// lets start with the email confirmation
			$email_order = STORE_NAME . "\n" .
			EMAIL_SEPARATOR . "\n" .
			EMAIL_TEXT_ORDER_NUMBER . ' ' . $insert_id . "\n" .
			EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $insert_id, 'SSL', false) . "\n" .
			EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n";
			if ($order->info['comments']) {
				$email_order .= tep_db_output($order->info['comments']) . "\n\n";
			}
			$email_order .= EMAIL_TEXT_PRODUCTS . "\n" .
			EMAIL_SEPARATOR . "\n" .
			$products_ordered .
			EMAIL_SEPARATOR . "\n";
				
			for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
				$email_order .= strip_tags($order_totals[$i]['title']) . ' ' . strip_tags($order_totals[$i]['text']) . "\n";
			}
			// brandtd - adapted send/billto ID 2 usage of session var
			if ($order->content_type != 'virtual') {
				$email_order .= "\n" . EMAIL_TEXT_DELIVERY_ADDRESS . "\n" . EMAIL_SEPARATOR . "\n";

				if($basket->status() == IC_ORDER_WAIT) {
					$email_order .= $icLang->getParam('ORDER_WAITING');
				} else {
					$email_order .= tep_address_label($customer_id, $_SESSION['sendto'], 0, '', "\n");
				}
				 
				$email_order .= "\n";
			}
				
			$email_order .= "\n" . EMAIL_TEXT_BILLING_ADDRESS . "\n" . EMAIL_SEPARATOR . "\n" ;

			if($basket->status() == IC_ORDER_WAIT) {
				$email_order .= $icLang->getParam('ORDER_WAITING');
			} else {
				$email_order .= tep_address_label($customer_id, $_SESSION['billto'], 0, '', "\n");
			}
			$email_order .= "\n\n";
				
			$email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" .  EMAIL_SEPARATOR . "\n";
			$email_order .= $icLang->getParam('MODULE_TITLE_EMAIL') . "\n\n";

			//TODO: check functionality of email_footer
			//		    if ($payment_class->email_footer) {
			//		      $email_order .= $payment_class->email_footer . "\n\n";
			//		    }

			tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'],
			$order->customer['email_address'],
			EMAIL_TEXT_SUBJECT,
			nl2br($email_order),
			STORE_OWNER,
			STORE_OWNER_EMAIL_ADDRESS,
			           '');
				
			// send emails to other people
			if (SEND_EXTRA_ORDER_EMAILS_TO != '') {
				tep_mail('', SEND_EXTRA_ORDER_EMAILS_TO, EMAIL_TEXT_SUBJECT, nl2br($email_order), STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS, '');
			}
				
			if($rc = $basket->orderID($icOrderID)) {
				if($basket->status() == IC_ORDER_WAIT) {
					$this->maskOrder();
				}
			}

			tep_session_unregister('sendto');
			tep_session_unregister('billto');
			tep_session_unregister('shipping');
			tep_session_unregister('payment');
			tep_session_unregister('comments');
			$cart->reset(true);

			// OSC checkout_process.php END
		}
		 
		return $rc;
	}

	// this function is called in calls from iclear server as initiator - shop environemnt only loaded throug config!

	function maskOrder() {
		$rc = false;
		$basket =& $this->icCore->getBasket();
		if($orderID = $basket->orderID()) {
			$lang = $this->getLanguage();
			$fields = false;
			foreach(array('delivery', 'billing') AS $prefix) {
				foreach($this->addressKeysMask AS $key => $val) {
					//tep_db_prepare_input($order->$prefix[$key])
					$fields[] = $prefix.'_'.$key . ' = ' . ($val == 'info' ? '"'.$lang->getParam('ORDER_WAITING').'"' : '"**********"');
				}
			}
			if($fields) {
				$sql = 'UPDATE ' . TABLE_ORDERS . ' SET ' . implode(',', $fields) . ' WHERE orders_id = ' . $orderID . ' LIMIT 1';
				$rc = tep_db_query($sql);
			}
		}
		return $rc;
	}

	function unmaskOrder() {
		$rc = false;
		$basket = $this->icCore->getBasket();
		if($orderID = $basket->orderID()) {
			$order = $basket->getOrder();
			$fields = false;
			foreach(array('delivery', 'billing') AS $prefix) {
				$src = $order->$prefix;
				foreach($this->addressKeysUnmask AS $key) {
					$fields[] = $prefix.'_'.$key . ' = "' . tep_db_prepare_input($src[$key]) .'"';
				}
			}
			if($fields) {
				$fields[] = 'delivery_name = "' . $order->delivery['firstname'] . ' ' . $order->delivery['lastname'] . '"';
				$fields[] = 'billing_name = "' . $order->billing['firstname'] . ' ' . $order->billing['lastname'] . '"';
				$fields[] = 'orders_status = "' . MODULE_PAYMENT_ICLEAR_ORDER_STATUS_ID . '"';
				$sql = 'UPDATE ' . TABLE_ORDERS . ' SET ' . implode(',', $fields) . ' WHERE orders_id = ' . $orderID . ' LIMIT 1';
				$rc = tep_db_query($sql);
			}
		}
		return $rc;
	}

	function cancelOrder($orderID = 0) {
		// TODO: what's about to check the order undo result (always true correct)?
		$rc = true;
		$orderID = (int) $orderID;
		if($orderID) {
			$sql = "SELECT products_id, products_quantity from " . TABLE_ORDERS_PRODUCTS . " WHERE orders_id = '" . (int)$orderID . "'";
			$pqry = tep_db_query($sql);

			while ($product = tep_db_fetch_array($pqry)) {
				tep_db_query("UPDATE " . TABLE_PRODUCTS . " SET " .
                         "products_quantity = products_quantity + " . $product['products_quantity'] . ", " .
                         "products_ordered = products_ordered - " . $product['products_quantity'] .
                       " WHERE products_id = '" . (int)$product['products_id'] . "'");
			}
			tep_db_query('DELETE FROM ' . TABLE_ORDERS_PRODUCTS . ' WHERE orders_id = "' . $orderID . '"');
			tep_db_query('DELETE FROM ' . TABLE_ORDERS . ' WHERE orders_id = "' . $orderID . '" LIMIT 1');
		}
		return $rc;
	}

	function shopURL() {
		$rv = '';
		$basket =& $this->icCore->getBasket();
		$icSessionParam = IC_SESSION_NAME . '=' . $basket->sessionID();
		if($basket->orderAccepted()) {
			if($this->status == IC_ORDER_CANCEL) {
				if ( $this->bIframe )
				$rv = tep_href_link('checkout_iclear.php', 'ic_cancel=1', 'SSL'); // 20110203 CA - fixed link
				else
				$rv = tep_href_link(FILENAME_DEFAULT, $icSessionParam, 'SSL');
			} else {
				if ( $this->bIframe ) {
					$_SESSION['ic_processed'] = true;
					$rv = tep_href_link('checkout_iclear.php',  IC_SESSION_NAME . '=' . $basket->sessionID() . '&ic_processed=1', 'SSL');
				} else {
					$rv = tep_href_link(FILENAME_CHECKOUT_SUCCESS, $icSessionParam, 'SSL');
				}
			}
		} else {
			$lang =& $this->icCore->getLanguage();
			if ( $this->bIframe )
			$rv =  tep_href_link('checkout_iclear.php', 'error_message=' . urlencode($lang->getParam('TRANSACTION_ERROR')) . '&ic_cancel=1', 'SSL'); // 20110203 CA - fixed link
			else
			$rv = tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode($lang->getParam('TRANSACTION_ERROR')), 'SSL'); // 20110203 CA - fixed link
		}
		return str_replace('&amp;', '&', $rv); //20110203 CA - removed gambio bugs
	}

	/**
	 * Following methods expected 2 be exist by the enclosing shop system
	 */

	function update_status() {

		$order =& $this->getOrder();

		if ( $order && ($this->enabled == true) && ((int)MODULE_PAYMENT_ICLEAR_ZONE > 0) ) {
			$check_flag = false;
			$check_query = $this->dbQuery("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_ICLEAR_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id");
			while ($check = $this->dbFetchRecord($check_query)) {
				if ($check['zone_id'] < 1) {
					$check_flag = true;
					break;
				} elseif ($check['zone_id'] == $order->billing['zone_id']) {
					$check_flag = true;
					break;
				}
			}

			if ($check_flag == false) {
				$this->enabled = false;
			}
		}
	}

	function javascript_validation() {
		return false;
	}

	function selection() {
		$out = array();
		$out = array_merge($out, array(
		array (
          'title' => ' ',
          'field' => $this->lang->getParam('INFO_EXTENDED')
		)
		)
		);

		return array (
        'id' => $this->code,
        'module' => $this->title,
        'fields' => $out,
        'description' => $this->lang->getParam('INFO_EXTENDED')
		);
	}

	function pre_confirmation_check() {
		return false;
	}

	function confirmation() {
		return false;
	}

	function process_button() {
		$rv = '';
		 
		unset($_SESSION['ic_processed']);
		//unset($_SESSION['icSessionID']);
		//unset($_SESSION['icBasketID']);
		 
		$soap =& $this->icCore->getObject('IclearSOAP');
		$rv = tep_draw_hidden_field('icRedirect', 1);
		if(!$this->icCore->perform($soap, IC_SOAP_SENDORDER_METHOD)) {
			$lang =& $this->icCore->getLanguage();
			$rv .= tep_draw_hidden_field('icErrorURL',
			urlencode($lang->getParam('TRANSACTION_ERROR'))
			);
				
			if ( !$this->bIframe )
			$rv .= tep_draw_hidden_field('icErrorMessage', 'error_message=' . urlencode($soap->lastError()) );
		}
		return $rv;
	}

	function before_process() {
		$basket =& $this->icCore->getBasket();
		// if there's no wsdlResult, no confirmation was done!
		 
		if(preg_match('/checkout_iclear/', $_SERVER['SCRIPT_FILENAME'])) {
			return;
		}

		if(isset($_POST['icRedirect']) && ($url = $basket->iclearURL())) {
			if ( !$this->bIframe )
			tep_redirect($url);
			else
			tep_redirect(tep_href_link('checkout_iclear.php'));
			exit();
		}
		$lang =& $this->icCore->getLanguage();
		tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, '&error_message=' . urlencode($lang->getParam('TRANSACTION_ERROR'))));
		exit();
	}

	function after_process() {
		return false;
	}

	function output_error() {
		return false;
	}

	function check() {
		return $this->enabled() ? 1 : 0;
	}

	function install() {
		if($this->installTable()) {
			tep_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (" .
                       "configuration_title, " . 
                       "configuration_key, " . 
                       "configuration_value, ". 
                       "configuration_description, " . 
                       "configuration_group_id, " . 
                       "sort_order, " . 
                       "set_function, " . 
                       "date_added" . 
                     ") VALUES (" .
                       "'Aktivieren', ". 
                       "'MODULE_PAYMENT_ICLEAR_STATUS', " . 
                       "'True', " .
                       "'Wollen Sie Zahlungen per iclear Paymentsystem anbieten?', " .
                       "'6', " . 
                       "'0', " . 
                       "'tep_cfg_select_option(array(\'True\', \'False\'), ', ".
                       "NOW()" . 
                      ")");

			tep_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (" .
                       "configuration_title, " .
                       "configuration_key, " .
                       "configuration_value, " .
                       "configuration_description, " .
                       "configuration_group_id, " .
                       "sort_order, " .
                       "date_added" . 
                     ") VALUES (" . 
                       "'iclear Shop ID', " .
                       "'MODULE_PAYMENT_ICLEAR_ID', " .
                       "'ShopID', " .
                       "'Ihre iclear Shop ID', " .
                       "'6', " .
                       "'0', " .
                       "NOW()" .
                     ")");

			tep_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (" .
                       "configuration_title, " .
                       "configuration_key, " .
                       "configuration_value, " .
                       "configuration_description, " .
                       "configuration_group_id, " .
                       "sort_order, " .
                       "date_added" . 
                     ") VALUES (" . 
                       "'Reihenfolge der Anzeige.', " .
                       "'MODULE_PAYMENT_ICLEAR_SORT_ORDER', " .
                       "'0', " .
                       "'Niedrigste wird zuerst angezeigt.', " .
                       "'6', " .
                       "'0', " .
                       "NOW()" . 
                     ")");

			tep_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (" .
                       "configuration_title, " .
                       "configuration_key, " .
                       "configuration_value, " .
                       "configuration_description, " .
                       "configuration_group_id, " .
                       "sort_order, " .
                       "use_function, " .
                       "set_function, " .
                       "date_added" . 
                     ") VALUES (" . 
                       "'Zone f&uuml;r diese Zahlungsweise', " .
                       "'MODULE_PAYMENT_ICLEAR_ZONE', " .
                       "'0', " .
                       "'Wenn Sie eine Zone ausw&auml;hlen, wird diese Zahlungsweise nur in dieser Zone angeboten.', " .
                       "'6', " .
                       "'0', " .
                       "'tep_get_zone_class_title', " .
                       "'tep_cfg_pull_down_zone_classes(', " .
                       "NOW()" . 
                     ")");

			// create iclear waiting order status
			$status = $this->dbFetchRecord('SELECT orders_status_id FROM ' . TABLE_ORDERS_STATUS . ' ORDER BY orders_status_id DESC LIMIT 1');

			if(is_array($status) && $status['orders_status_id']) {
				$status['orders_status_id']++;
			} else {
				$status['orders_status_id'] = 1;
			}

			tep_db_query('INSERT INTO ' . TABLE_ORDERS_STATUS . ' ' .
                       '(orders_status_id, language_id, orders_status_name) ' . 
                     'VALUES ' .
                       '(' . $status['orders_status_id'] . ', 1, "iclear pending" )');
			 
			tep_db_query('INSERT INTO ' . TABLE_ORDERS_STATUS . ' ' .
                       '(orders_status_id, language_id, orders_status_name) ' .
                      'VALUES ' .
                      '(' . $status['orders_status_id'] . ', 2, "iclear wartend" )');

			tep_db_query('INSERT INTO ' . TABLE_ORDERS_STATUS . ' ' .
                       '(orders_status_id, language_id, orders_status_name) ' .
                      'VALUES ' .
                       '(' . $status['orders_status_id'] . ', 3, "iclear pendiente" )');

			tep_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (" .
                       "configuration_title, " .
                       "configuration_key, " .
                       "configuration_value, " .
                       "configuration_description, " .
                       "configuration_group_id, " .
                       "sort_order, " .
                       "date_added" . 
                     ") VALUES (" .
                       "'Waiting orders ID', " .
                       "'MODULE_PAYMENT_ICLEAR_STATUS_WAIT_ID', " .
                       "'" . $status['orders_status_id'] . "', " .
                       "'Iclear waiting orders state - only for internal use', " .
                       "'6', " .
                       "'0', " .
                       "NOW()" .
                     ")");

			tep_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (" .
			   "configuration_title, " . 
			   "configuration_key, " . 
			   "configuration_value, ". 
			   "configuration_description, " . 
			   "configuration_group_id, " . 
			   "sort_order, " . 
			   "set_function, " . 
			   "date_added" . 
			 ") VALUES (" .
			   "'iframe', ". 
			   "'MODULE_PAYMENT_ICLEAR_IFRAME', " . 
			   "'True', " .
			   "'iclear im iframe anzeigen', " .
			   "'6', " . 
			   "'0', " . 
			   "'tep_cfg_select_option(array(\'True\', \'False\'), ', ".
			   "NOW()" . 
			  ")");
		}
	}

	function remove() {
		tep_db_query("DELETE from " . TABLE_CONFIGURATION . " WHERE configuration_key in ('" . implode("', '", $this->keys(true)) . "')");
		// iclear
		// check 4 lagging orders, restock and delete 'em
		$status_qry = tep_db_query('SELECT orders_status_id FROM ' . TABLE_ORDERS_STATUS . ' WHERE orders_status_name LIKE "iclear%" LIMIT 1');
		$status = tep_db_fetch_array($status_qry);
		if(is_array($status) && $status['orders_status_id']) {
			// check if there are any lagging orders in the orders table
			// if, remove them and update stock and orders history
			$orders_qry = tep_db_query('SELECT orders_id FROM ' . TABLE_ORDERS . ' WHERE orders_status = ' . $status['orders_status_id']);
			if($orders_qry) {
				while($order = tep_db_fetch_array($orders_qry)) {
					$this->cancelOrder($order['orders_id']);
				}
			}
		}
		tep_db_query('DELETE FROM ' . TABLE_ORDERS_STATUS . ' WHERE orders_status_name LIKE "iclear%"');
	}

	function keys($all = false) {
		$rv = array(
        'MODULE_PAYMENT_ICLEAR_STATUS',
        'MODULE_PAYMENT_ICLEAR_ID',
        'MODULE_PAYMENT_ICLEAR_ZONE',
        'MODULE_PAYMENT_ICLEAR_SORT_ORDER',
		'MODULE_PAYMENT_ICLEAR_IFRAME',
		);
		if($all) {
			$rv[] = 'MODULE_PAYMENT_ICLEAR_STATUS_WAIT_ID';
		}

		return $rv;
	}

	function pageparams ( ) {
		$Param = array( );
		if ( $this->bIframe ) {
			$Param['mode'] = 'inline';
		}
		else {
			$Param['mode'] = 'std';
		}
		return $Param;
	}

}
?>